package Square;

import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;

import Monopol.MonopolExceptions.InsufficientFunds;
import Monopol.AssetGroups.AssetGroup;
import Monopol.AssetGroups.State;
import Player.Player;

/**
 * @author Avia Tam
 * @author Assaf Miron
 * 
 */
public class City extends Square implements Negotiable {

    private static final Integer MAX_HOUSES = 3;
    private Double[] stay_price; // Four Price Values
    private Double cost; // Cost of the City
    private Double house_price; // Cost of building Each House
    private Integer num_of_houses; // Indicator for the Number of Houses built
    private State state;// The State that this City relates to
    private Player owner; // The Player who Owns this Square

    /**
     * @param name
     * @param stay_price
     * @param cost
     * @param house_price
     * @param state
     */
    public City(String name, Double[] stay_price, Double cost, Double house_price, State state) {
	super(name); // Construct Square
	this.stay_price = stay_price; // Initialize the Stay Price Array
	this.cost = cost; // Initialize the Cost of the City
	this.house_price = house_price; // Initialize the Cost of each House
	this.num_of_houses = 0; // Initialize the number of houses - no Houses
	this.state = state; // Initialize the State
    }

    // Stay Price Getter and Setter
    @Override
    public Double getStay_price() {
	return stay_price[num_of_houses];
    }

    public void setStay_price(Double[] stay_price) {
	this.stay_price = stay_price;
    }
    // End-Stay Price Getter and Setter

    // Cost Getter and Setter
    @Override
    public Double getCost() {
	return cost;
    }

    public void setCost(Double cost) {
	this.cost = cost;
    }
    // End-Cost Getter and Setter

    // House Price Getter and Setter
    public Double getHouse_price() {
	return house_price;
    }

    public void setHouse_price(Double house_price) {
	this.house_price = house_price;
    }
    // End - House Price Getter and Setter

    // Number of Houses Getter and Setter
    public Integer getNum_of_houses() {
	return num_of_houses;
    }
    // End - Number of Houses Getter and Setter

    // State Getter and Setter
    public State getState() {
	return state;
    }

    public void setState(State state) {
	this.state = state;
    }
    // End- State Getter and Setter

    /**
     * @param Player The Square owner
     */
    @Override
    public void setOwner(Player player) {
	this.owner = player;
    }

    @Override
    public Player getOwner() {
	return owner;
    }

    /**
     * @return If the city can be bought
     */
    @Override
    public boolean isBuyable() {
	// Check if This Service has an Owner
	if (this.getOwner() == null) {
	    return true;
	} // No Owner - Can be Bought
	else {
	    return false;
	} // This Service has an Owner - Can't be bought
    }

    /**
     * @return If the city can be sold
     */
    @Override
    public boolean isSellable() {
	// Check if this Service has an Owner or not
	if (this.getOwner() != null) {
	    return true;
	} // The Owner can Sell this Service
	else {
	    return false;
	} // There is no Owner to the Service
    }


    /* (non-Javadoc)
     * @see Square.Negotiable#buy(Player.Player)
     */
    @Override
    public void buy(Player player) throws InsufficientFunds {
	// Check if the Player have enough Funds to buy this Service
	if (player.getFunds() >= this.cost) {
	    // Take the Money from the Player
	    player.addFunds(-this.cost);
	    // Set the Player as the Owner of this Service
	    this.setOwner(player);
	} else {
	    throw new InsufficientFunds("Insufficient Funds, can't buy ");
	}

    }

    @Override
    public void sell(Player player) {
	// Change the Owner of this City
	this.owner = player;
    }

    /**
     * Prints out The City Description
     */
    @Override
    public String toString() {
	String message = super.toString() + " (" + state.getName() + ")\n";

	// Check that there is a Owner
	if (owner != null) {
	    message = message
		    + "Stay Price: " + stay_price[num_of_houses] + "\n"
		    + "House Cost: " + house_price + "\n"
		    + "City Owner: " + owner.getName();
	} else // No Owner
	{
	    message = message
		    + "City Cost: " + cost.toString() + "\n"
		    + "Stay Price: \n"
		    + "\tNo Houses: " + stay_price[0] + "\n"
		    + "\tOne House: " + stay_price[1] + "\n"
		    + "\tTwo Houses: " + stay_price[2] + "\n"
		    + "\tThree Houses: " + stay_price[3] + "\n"
		    + "City Owner: NONE";
	}
	// Return the message
	return message;
    }

    @Override
    public boolean isAsset() {
	return true;
    }

    /**
     * verify and sells a house to the city owner if possible
     */
    public void buyHouse(Player player) throws InsufficientFunds {
	// Check if the Player have enough Funds to buy this Service
	if (player.getFunds() >= this.getHouse_price()) {
	    // Check that the Player wont buy more houses than it can
	    if (this.num_of_houses < MAX_HOUSES) {
		// Take the Money from the Player
		player.addFunds(-this.getHouse_price());
		//Raise house on state flag
		this.state.setIsHouseExists(true);
		// Increment the House Number
		this.num_of_houses++;
	    }
	} else {
	    throw new InsufficientFunds("Insufficient Funds, can't buy a house ");
	}

    }

    @Override
    public Boolean isCity() {
	return true;
    }

    @Override
    public void deleteOwner() {
	// Clear Owner
	owner = null;
	// Clear Number Of Houses
	num_of_houses = 0;
	// Clear the House Flag
	state.setIsHouseExists(false);
    }

    @Override
    public AssetGroup getGroup() {
	return state;
    }

    @Override
    public Color getColor() {
	// Check if there is an Owner for this Service
	if (owner != null) {
	    return owner.getColor();
	} else {
	    return state.getColor();
	}
    }

    /**
     * @return The City Details
     */
    @Override
    public String getDetails() {
	String retDetails;

	retDetails = "<P>"
		+ "City Cost: " + cost.toString() + "<BR>"
		+ "House Cost: " + "<B>" + house_price + "</B><BR>"
		+ "Stay Price: <BR>"
		+ "\tNo Houses: " + "<B>" + stay_price[0] + "</B><BR>"
		+ "\tOne House: " + "<B>" + stay_price[1] + "</B><BR>"
		+ "\tTwo Houses: " + "<B>" + stay_price[2] + "</B><BR>"
		+ "\tThree Houses: " + "<B>" + stay_price[3] + "</B><BR>"
		+ "\tCity Owner: ";

	// Check that there is a Owner
	if (owner != null) {
	    retDetails = retDetails + "<B>" + owner.getName() + "</B>";
	} else // No Owner
	{
	    retDetails = retDetails + "<B>NONE</B>";
	}

	// Return the City Details
	return retDetails + "</P>";
    }

    @Override
    public JPanel draw() {
	// Create the Main Panel
	JPanel pnDetails = new JPanel();
	pnDetails.setLayout(new FlowLayout());
	pnDetails.setOpaque(false);

	// Create the Detail Labels
	JLabel lblDetails = new JLabel(getDetails(), JLabel.CENTER);

	// Add the Details Label to the Center
	pnDetails.add(lblDetails);

	// Return the Details Panel
	return pnDetails;
    }
}
